package com.yunxin.core.application.service.impl;

import com.yunxin.core.application.command.utils.EnumOptionCommand;
import com.yunxin.core.application.dto.utils.EnumOptionDTO;
import com.yunxin.core.application.service.EnumOptionQueryService;
import com.yunxin.core.utils.infra.common.enums.*;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;

/**
 * @author zero°
 * @since 2023-05-28
 */
@Service
public class EnumOptionQueryServiceImpl implements EnumOptionQueryService, ApplicationContextAware {

    private static final Map<EnumOptionTypeEnum, Function<EnumSourceTypeEnum, List<EnumOptionDTO>>> ENUM_OPTION_MAP = new EnumMap<>(EnumOptionTypeEnum.class);

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.ACCUMULATION_FUND_LEVEL, this::accumulationFundLevel);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.CREDIT_CARD, this::creditCard);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.EDUCATION_LEVEL, this::educationLevel);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.HOUSE_LEVEL, this::houseLevel);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.INSURE, this::insure);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.MICRO_LOAN_QUOTA, this::microLoanQuota);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.SESAME_SEED_QUOTA, this::sesameSeedQuota);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.SOCIAL_SECURITY_LEVEL, this::socialSecurityLevel);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.VEHICLE_LEVEL, this::vehicleLevel);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.OCCUPATION, this::occupation);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.OCCUPATION_INCOME, this::occupationIncome);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.JD_BT_QUOTA, this::jdBtQuota);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.ANT_CREDIT_PAY_QUOTA, this::antCreditPayQuota);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.SEX, this::sex);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.BE_OVERDUE, this::beOverdue);
        ENUM_OPTION_MAP.put(EnumOptionTypeEnum.LOAN_PERIOD, this::loanPeriod);

    }


    @Override
    public List<EnumOptionDTO> listEnumOption(EnumOptionCommand request) {
        Function<EnumSourceTypeEnum, List<EnumOptionDTO>> function =  ENUM_OPTION_MAP.get(request.getEnumOptionType());
        if (Objects.isNull(function)) {
            return Collections.emptyList();
        }
        return function.apply(request.getSourceType());
    }

    /**
     * 公积金情况枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> accumulationFundLevel(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (AccumulationFundLevelEnum value : AccumulationFundLevelEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && AccumulationFundLevelEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 信用卡枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> creditCard(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (CreditCardEnum value : CreditCardEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && CreditCardEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 教育情况枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> educationLevel(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (EducationLevelEnum value : EducationLevelEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && EducationLevelEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 房产情况枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> houseLevel(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (HouseLevelEnum value : HouseLevelEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && HouseLevelEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 寿险年限枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> insure(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (InsureEnum value : InsureEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && InsureEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 微粒贷额度枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> microLoanQuota(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (MicroLoanQuotaEnum value : MicroLoanQuotaEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && MicroLoanQuotaEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 芝麻信用分额度枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> sesameSeedQuota(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (SesameSeedQuotaEnum value : SesameSeedQuotaEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && SesameSeedQuotaEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 社保情况枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> socialSecurityLevel(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (SocialSecurityLevelEnum value : SocialSecurityLevelEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && SocialSecurityLevelEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 车产情况枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> vehicleLevel(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (VehicleLevelEnum value : VehicleLevelEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && VehicleLevelEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 职业枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> occupation(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (OccupationEnum value : OccupationEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && OccupationEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 职业收入枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> occupationIncome(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (OccupationIncomeEnum value : OccupationIncomeEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && OccupationIncomeEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 京东白条额度枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> jdBtQuota(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (JdBtQuotaEnum value : JdBtQuotaEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && JdBtQuotaEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 蚂蚁花呗额度枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> antCreditPayQuota(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (AntCreditPayEnum value : AntCreditPayEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && AntCreditPayEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 性别枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> sex(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (SexEnum value : SexEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && SexEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 性别枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> beOverdue(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (BeOverdueEnum value : BeOverdueEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && BeOverdueEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dto.setExcellent(value.getExcellent());
            dtoList.add(dto);
        }
        return dtoList;
    }


    /**
     * 借款期限枚举
     * @param sourceTypeEnum sourceTypeEnum
     * @return List<EnumOptionDTO>
     */
    private List<EnumOptionDTO> loanPeriod(EnumSourceTypeEnum sourceTypeEnum){
        List<EnumOptionDTO> dtoList = new ArrayList<>();
        for (LoanPeriodEnum value : LoanPeriodEnum.values()) {
            if (EnumSourceTypeEnum.USER.equals(sourceTypeEnum) && LoanPeriodEnum.NO_REQUIRED.equals(value)){
                continue;
            }
            EnumOptionDTO dto = new EnumOptionDTO();
            dto.setValue(value.getValue());
            dto.setLabel(value.getLabel());
            dtoList.add(dto);
        }
        return dtoList;
    }


}
